/*!
 * \file frsutl.h
 *
 * \brief 常用函数
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 * 相关接口，实现常用函数
 *
 * \version 2.0
 * \author yaohl
 * \date 2014/11/10
 *
 */
#ifndef __FRSUTL_H_
#define __FRSUTL_H_

#include <stdint.h>
#include <stdlib.h>

/* apm中使用uuid的数据长度 */
#define APM_UUID_SIZE  37

/* 数据类型转换  */
typedef union __un_data_bits
{
    short b_value;
    char  c_value;
    short s_value;
    int   i_value;
    long  l_value;
    long long ll_value;
    float f_value;
    double d_value;
    char arr_value[8];
} Frdata_bits;

/*!
 * 生成uuid
 *
 * \param p_uuid    (生成uuid数据)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 * \note 数据空间长度必须>=37
 *
 */
int  fruuid(char *p_uuid);

/*!
 * 字符串ip转换成数字ip
 *
 * \param dotted    (字符串形式的ip)
 *
 * \return 数字的ip
 *
 * \note 转换不了时返回0
 *
 */
u_int iptools_parse_ipaddr(const char *dotted);

/*!
 * 字符串ip段转换成起始ip和结束ip
 *
 * \param dotted    (字符串形式的ip段)
 * \param min_ip    (起始ip地址)
 * \param max_ip    (结束ip地址)
 *
 */
void iptools_parse_iprange(const char* dotted, u_int* min_ip, u_int* max_ip);

/*!
 * 端口段转换成起始端口和结束端口
 *
 * \param dotted     (字符串形式的端口段)
 * \param sport      (起始端口)
 * \param dport      (结束端口)
 *
 */
void iptools_parse_portrange(const char* dotted, u_short* sport, u_short* dport);

/*!
 * 字符串mac地址转换成标准内存
 *
 * \param str_mac    (字符串形式的mac)
 * \param mac        (标准形式mac地址)
 * \param size       (标准形式mac地址的长度)
 *
 * \return 0  失败\n
 *         1  成功
 *
 * \note 转换不了时返回0
 *
 */
int  iptools_parse_mac(char* str_mac, unsigned char* mac, int size);

/*!
 * 取得应用程序的绝对路径
 *
 * \param p_relative_path    (应用程序名,带路径)
 * \param p_abs_dir          (获取应用程序的绝对路径)
 * \param ui_size            (p_abs_dir空间大小)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int  frget_absdir(char *p_relative_path, char *p_abs_dir, unsigned int ui_size);

/*!
 * 将struct timeval的时间转换为本地时间
 *
 * \param p_tv               (struct timeval结构体指针)
 * \param p_time             将struct timeval的时间\n
 *                           转换年/月/日  时:分:秒.微秒格式输出
 * \param ui_time_size       p_time的空间大小
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 * \note 
 *
 */
int  frtime2str(struct timeval *p_tv , char *p_time, unsigned int ui_time_size);

/*!
 * 计算两个时间戳的差（以微秒显示）
 *
 * \param p_tv_pre          前一个时间戳
 * \param p_tv_now          当前时间戳
 *
 * \return time_diff        返回时间差( 当前时间戳 - 前一个时间戳)
 *
 */
long frtime_diff(struct timeval *p_tv_pre, struct timeval *p_tv_now);

/*!
 * 用于没有数据结尾符的数据出力，使用log出力
 *
 * \param p_title    (出力数据抬头)
 * \param p_data     (数据)
 * \param ui_size    (数据长度)
 *
 */
void frprint_bin(const char *p_fun, const char *p_file, unsigned int ui_line
               , const char *p_title, const char *p_data, unsigned int ui_size);
#define FRPRINT_BIN(a,b,c) frprint_bin(__func__,__FILE__,__LINE__, a, b, c)

/*!
 * l4信息获取
 *
 * \param us_proto  (协议 tcp/udp)
 * \param ui_src    (原地址)
 * \param us_sport  (原端口)
 * \param ui_dest   (目的地址)
 * \param us_dport  (目的端口)
 *
 */
void frl4_info(u_short ip_proto, u_int src_ip, u_short src_port, u_int dst_ip,u_short dst_port
              , unsigned int ui_data_len
              , int i_analyz_cmd
              , char *p_outbuff, unsigned int ui_buff_size);

/*******************************************************************************
*  FUNC     :  l4信息打印
*  ARGS     :  us_proto  (协议 tcp/udp)
*           :  ui_src    (原地址)
*           :  us_sport  (原端口)
*           :  ui_dest   (目的地址)
*           :  us_dport  (目的端口)
*  RTN      :
*  NOTE     :
*******************************************************************************/
void frl4_print(const char *p_fun, const char *p_file, unsigned int ui_line
              , u_short ip_proto, u_int src_ip, u_short src_port, u_int dst_ip,u_short dst_port
              , unsigned int ui_data_len
              , int analyz_cmd);
#define FRPRINT_L4(ip_proto, src_ip, src_port, dst_ip, dst_port, ui_data_len, analyz_cmd)  \
        frl4_print(__func__,__FILE__,__LINE__, ip_proto, src_ip, src_port, dst_ip, dst_port, ui_data_len, analyz_cmd)

/*!
 * l4信息调试
 *
 * \param p_buff       (出力内存空间)
 * \param ui_buff_size (出力内存空间大小)
 * \param us_proto     (协议 tcp/udp)
 * \param ui_src       (原地址)
 * \param us_sport     (原端口)
 * \param ui_dest      (目的地址)
 * \param us_dport     (目的端口)
 *
 */
void frl4_print2(char *p_buff, unsigned int ui_buff_size
                ,u_short ip_proto, u_int src_ip, u_short src_port, u_int dst_ip,u_short dst_port);

/*!
 * 去除字符串的头尾的空格
 *
 * \param p_instr          传入字符串的指针
 *
 */
void frtrim(char *p_instr);

/*!
 * 去除字符串的尾的空格
 *
 * \param p_instr          传入字符串的指针
 *
 */
void frrtrim(char *p_instr);

/*!
 * 去除字符串的头的空格
 *
 * \param p_instr          传入字符串的指针
 *
 */
void frltrim(char *p_instr);

/*!
 * 去除字符串的尾的[\r\n]/[\n]
 *
 * \param p_instr          传入字符串的指针
 *
 */
void frrtrimLF(char *p_instr);

/*!
 * 字符串查询(没有\0的限制)
 *
 * \param p_data           原字符串
 * \param i_data_len       原字符串长度
 * \param p_substr         查询字符串
 * \param i_sublen         查询字符串长度
 *
 * \return NULL:没有查询到\n
 *         查询到的位置
 *
 */
char* frmemstr(const char* p_data, int i_data_len, char* p_substr, int i_sublen);

/*!
 * 转化为小写
 *
 * \param p_data           原字符串   (转化后的内存覆盖)
 * \param i_data_len       原字符串长度
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frstrlower(char *p_data, int i_data_len);

/*!
 * 转化为大写
 *
 * \param p_data           原字符串   (转化后的内存覆盖)
 * \param i_data_len       原字符串长度
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 *
 */
int frstrupper(char *p_data, int i_data_len);

/*!
 * 本地序转网络序
 *
 * \param u64_val          (uint64_t)
 *
 * \return uint64_t
 */
uint64_t frhton64(uint64_t u64_val);
#define frhton32(x)   htonl(x)
#define frhton16(x)   htons(x)

/*!
 * 网络序转本地序
 *
 * \param u64_val          (uint64_t)
 *
 * \return uint64_t
 */
uint64_t frntoh64(uint64_t u64_val);

/*!
 * 拷贝文件
 *
 * \param p_src_file        (源文件)
 * \param p_dst_file        (目标文件)
 *
 * \return FR_SUCC:成功\n
 *         FR_FAIL:失败
 */
int frcopy_file(const char *p_src_file, const char *p_dst_file);


/*!
 * 判断字符串中是否有不可见字符
 *
 * \param p_data  (输入的字符串)
 *        i_len   (输入的字符串长度)
 *
 * \return 1   无不可见字符\n
 *         0   有不可见字符
 *
 * \note tab,\n, \r\n认为是可见字符
 *
 */
int fris_print_ascii(char *p_data, int i_len);

#endif

